/********************************************************/
/*	Copyright (C) 2016 Gong Li Bin		 	*/
/*	Project:	GlbLib-1.0.0			*/
/*	Author:		gong_libin			*/
/*	Date:		2016_06_01			*/
/*	File:		GlbList.h			*/
/********************************************************/

#ifndef	_GLBLIST_H
#define	_GLBLIST_H

#include "GlbUtil.h"

namespace GlbCls
{

#define	GLB_HEAD			0x00
#define	GLB_TAIL			0x01

typedef	void* (*GLB_FUNDUP)(void*);
typedef	void (*GLB_FUNFREE)(void*);
typedef	int (*GLB_FUNMATCH)(void*, void*);

typedef struct tagGlbNode
{
	void* m_pValue;
	struct tagGlbNode* m_pstPrev;
	struct tagGlbNode* m_pstNext;
}GLBNODE_S;

typedef struct tagGlbIter
{
	int m_iDirection;
	GLBNODE_S* m_pstNext;
}GLBITER_S;

class CGlbList
{
public:
	CGlbList();
	virtual ~CGlbList();

	ULONG GlbListGetCount();
	GLBITER_S* GlbListGetIter();
	GLBNODE_S* GlbListGetHead();
	GLBNODE_S* GlbListGetTail();
	void* GlbListGetValue(GLBNODE_S* pstCur);
	GLBNODE_S* GlbListGetPrev(GLBNODE_S* pstCur);
	GLBNODE_S* GlbListGetNext(GLBNODE_S* pstCur);

	GLB_FUNDUP GlbListGetDup();
	GLB_FUNFREE GlbListGetFree();
	GLB_FUNMATCH GlbListGetMatch();

	void GlbListSetDup(GLB_FUNDUP);
	void GlbListSetFree(GLB_FUNFREE);
	void GlbListSetMatch(GLB_FUNMATCH);

	void GlbListRotate();
	void GlbListRelease();
	GLBNODE_S* GlbListNext();
	void GlbListRewindHead();
	void GlbListRewindTail();
	void GlbListIterator(int iDir);
	int GlbListDup(CGlbList& rCList);
	int GlbListAddHead(void* pValue);
	int GlbListAddTail(void* pValue);
	GLBNODE_S* GlbListIndex(long lIndex);
	GLBNODE_S* GlbListSearch(void* pKey);
	void GlbListDelete(GLBNODE_S* pstNode);
	int GlbListInsert(GLBNODE_S* pstBase, void* pValue, int iDir);

protected:
	ULONG m_ulCount;
	GLBITER_S m_stIter;
	GLBNODE_S* m_pstHead;
	GLBNODE_S* m_pstTail;

	void* (*m_pFunDup)(void*);
	void (*m_pFunFree)(void*);
	int (*m_pFunMatch)(void*, void*);

private:

};

inline ULONG CGlbList::GlbListGetCount()
{
	return m_ulCount;
}

inline GLBITER_S* CGlbList::GlbListGetIter()
{
	return &m_stIter;
}

inline GLBNODE_S* CGlbList::GlbListGetHead()
{
	return m_pstHead;
}

inline GLBNODE_S* CGlbList::GlbListGetTail()
{
	return m_pstTail;
}

inline void* CGlbList::GlbListGetValue(GLBNODE_S* pstCur)
{
	return pstCur->m_pValue;
}

inline GLBNODE_S* CGlbList::GlbListGetPrev(GLBNODE_S* pstCur)
{
	return pstCur->m_pstPrev;
}

inline GLBNODE_S* CGlbList::GlbListGetNext(GLBNODE_S* pstCur)
{
	return pstCur->m_pstNext;
}

inline GLB_FUNDUP CGlbList::GlbListGetDup()
{
	return m_pFunDup;
}

inline GLB_FUNFREE CGlbList::GlbListGetFree()
{
	return m_pFunFree;
}

inline GLB_FUNMATCH CGlbList::GlbListGetMatch()
{
	return m_pFunMatch;
}

inline void CGlbList::GlbListSetDup(GLB_FUNDUP pFunDup)
{
	m_pFunDup = pFunDup;

	return;
}

inline void CGlbList::GlbListSetFree(GLB_FUNFREE pFunFree)
{
	m_pFunFree = pFunFree;

	return;
}

inline void CGlbList::GlbListSetMatch(GLB_FUNMATCH pFunMatch)
{
	m_pFunMatch = pFunMatch;

	return;
}

} /* GlbCls */

#endif /* _GLBLIST_H */
